<?php

namespace app\push\controller;

/**
 * 用于检测业务代码死循环或者长时间阻塞等问题
 * 如果发现业务卡死，可以将下面declare打开（去掉//注释），并执行php start.php reload
 * 然后观察一段时间workerman.log看是否有process_timeout异常
 */
//declare(ticks=1);

/**
 * 聊天主逻辑
 * 主要是处理 onMessage onClose
 */

use \GatewayWorker\Lib\Gateway;
use Workerman\Lib\Timer;
use think\Db;

class Events
{
    /**
     * 有消息时
     * @param int $client_id
     * @param mixed $message
     */
    public static function onMessage($client_id, $message)
    {
        // debug
        echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id session:" . json_encode($_SESSION) . " onMessage:" . $message . "\n";

        // 客户端传递的是json数据
        $message_data = json_decode($message, true);
        //file_put_contents('txt.txt',json_encode($message_data).PHP_EOL,FILE_APPEND);

        if (!$message_data) {
            return;
        }

        // 根据类型执行不同的业务
        switch ($message_data['type']) {
                // 客户端回应服务端的心跳
            case 'pong':
                return;
                // 客户端登录 message格式: {type:login, name:xx, room_id:1} ，添加到客户端，广播给所有客户端xx进入聊天室
            case 'login':
                // 判断是否有房间号
                if (!isset($message_data['room_id'])) {
                    throw new \Exception("\$message_data['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message");
                }

                // 把房间号昵称放到session中
                $room_id = $message_data['room_id'];
                $client_name = htmlspecialchars($message_data['client_name']);
                $_SESSION['room_id'] = $room_id;
                $_SESSION['client_name'] = $client_name;

                // 获取房间内所有用户列表
                // $clients_list = Gateway::getClientSessionsByGroup($room_id);
                // foreach ($clients_list as $tmp_client_id => $item) {
                //     $clients_list[$tmp_client_id] = $item['client_name'];
                // }
                // $clients_list[$client_id] = $client_name;

                // 转播给当前房间的所有客户端，xx进入聊天室 message {type:login, client_id:xx, name:xx}
                // $new_message = array('type' => $message_data['type'], 'client_id' => $client_id, 'client_name' => htmlspecialchars($client_name), 'time' => date('Y-m-d H:i:s'));
                // Gateway::sendToGroup($room_id, json_encode($new_message));
                Gateway::joinGroup($client_id, $room_id);

                // 给当前用户发送用户列表
                // $new_message['client_list'] = $clients_list;
                // Gateway::sendToCurrentClient(json_encode($new_message));
                return;

                // 客户端发言 message: {type:say, to_client_id:xx, content:xx}
            case 'say':
                // 非法请求
                if (!isset($_SESSION['room_id'])) {
                    throw new \Exception("\$_SESSION['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']}");
                }
                $room_id = $_SESSION['room_id'] ? $_SESSION['room_id'] : $message_data['room_id'];
                $client_name = $_SESSION['client_name'] ? $_SESSION['client_name'] : '匿名';

                //添加聊天记录
                if ($message_data['user_id'] != '') {
                    $last = db('chat_details')->where('room_id', $message_data['room_id'])->order('id desc')->find();
                    $times = [];
                    if (!$last || $last['created_time'] + 600 < time()) {
                        $times = [
                            'user_id' => $message_data['user_id'],
                            'room_id' => $room_id,
                            'content' => totime(time()),
                            'created_time' => time(),
                            'type' => 1,
                        ];
                        db('chat_details')->insert($times);
                    }
                    $insertData = [
                        'user_id' => $message_data['user_id'],
                        'room_id' => $room_id,
                        // 'content' => htmlspecialchars($message_data['content']),
                        'content' => nl2br(htmlspecialchars(userTextEncode($message_data['content']))),
                        'created_time' => time(),
                        'type' => 0,
                    ];
                    db('chat_details')->insert($insertData);
                }
                $new_message = array(
                    'user_id' => $message_data['user_id'],
                    'type' => 'say',
                    'from_client_id' => $client_id,
                    'from_client_name' => $client_name,
                    'to_client_id' => $message_data['to_client_id'],
                    'content' => nl2br(htmlspecialchars($message_data['content'])),
                    // 'content' => $message_data['content'],
                    'time' => date('Y-m-d H:i:s'),
                    'ide' => $message_data['ide'],
                    'room_id' => $message_data['room_id']
                );
                $group = [
                    'type' => 'all',
                    'room_id' => $room_id,
                    'allids' => db('chat_rooms')->where('id', $room_id)->value('hideids'),
                    'group_name' => $message_data['group_name'],
                    // 'content' => $message_data['content'],
                    'content' => nl2br(htmlspecialchars($message_data['content'])),
                    'time' => date('H:i'),
                    'ide' => $message_data['ide'],
                    'groupide' => $message_data['groupide'],
                ];
                db('chat_rooms')->where('id', $room_id)->setField('hideids', '0');
                Gateway::sendToAll(json_encode($group));
                return Gateway::sendToGroup($room_id, json_encode($new_message));
            case 'login_client':

                // 把房间号昵称放到session中
                $client_name = htmlspecialchars($message_data['client_name']);
                $_SESSION['client_name'] = $client_name;
                // 转播给当前房间的所有客户端，xx进入聊天室 message {type:login, client_id:xx, name:xx}
                $new_message = array('type' => $message_data['type'], 'client_id' => $client_id, 'client_name' => htmlspecialchars($client_name), 'time' => date('Y-m-d H:i:s'));

                Gateway::bindUid($client_id, $message_data['user_id']);
                Gateway::sendToCurrentClient(json_encode($new_message));
                return;

                // 客户端发言 message: {type:say, to_client_id:xx, content:xx}
            case 'say_client':
                // 非法请求
                $client_name = $_SESSION['client_name'];
                $message_data['other_id'] = 1;
                // file_put_contents('txt.txt', json_encode($message_data).PHP_EOL,FILE_APPEND);
                $info = db('chat_rooms')->where("id", $message_data['room_id'])->find();
                if ($info) {
                    if ($info['user_id'] == $message_data['user_id']) {
                        $message_data['other_id'] = $info['other_id'];
                        $setField['o_unread'] = 1;
                    } else {
                        $message_data['other_id'] = $info['user_id'];
                        $setField['u_unread'] = 1;
                    }
                    $setField['is_u_show'] = 1;
                    $setField['is_o_show'] = 1;
                    $to_client_id = Gateway::getClientIdByUid($message_data['other_id']);

                    if ($message_data['user_id'] != '') {
                        $last = db('chat_details')->where('room_id', $message_data['room_id'])->order('id desc')->find();
                        $times = [];
                        if (!$last || $last['created_time'] + 600 < time()) {
                            $times = [
                                'user_id' => $message_data['user_id'],
                                'room_id' => $message_data['room_id'],
                                'content' => totime(time()),
                                'created_time' => time(),
                                'type' => 1,
                            ];
                            db('chat_details')->insert($times);
                        }
                        $insertData = [
                            'user_id' => $message_data['user_id'],
                            'room_id' => $message_data['room_id'],
                            // 'content' => $message_data['content'],
                            'content' => nl2br(htmlspecialchars(userTextEncode($message_data['content']))),
                            // 'content' => nl2br(htmlspecialchars($message_data['content'])),
                            'created_time' => time(),
                            'type' => 0,
                        ];
                        db('chat_details')->insert($insertData);
                        db('chat_rooms')->where("id", $message_data['room_id'])->setField($setField);
                    }

                    $new_message = array(
                        'user_id' => $message_data['user_id'],
                        'type' => 'say_client',
                        'from_client_id' => $client_id,
                        'from_client_name' => $client_name,
                        'content' => nl2br(htmlspecialchars($message_data['content'])),
                        // 'content' => $message_data['content'],
                        'created_time' => date('Y-m-d H:i:s'),
                        'room_id' => $message_data['room_id'],
                        'other_id' => $message_data['other_id'],
                        'time' => date('H:i'),
                        'ide' => $message_data['ide'],
                        'is_show' => $info['user_id'],
                    );

                    $times['type'] = 'times';
                    if ($to_client_id) {
                        foreach ($to_client_id as $key => $value) {
                            if ($times) {
                                Gateway::sendToClient($value, json_encode($times));
                            }
                            Gateway::sendToClient($value, json_encode($new_message));
                        }
                    }
                    $new_message['type'] = 'say_client_mi';
                    if ($times) {
                        Gateway::sendToCurrentClient(json_encode($times));
                    }
                    Gateway::sendToCurrentClient(json_encode($new_message));

                    return true;
                }

            case 'add_friend':
                $to_client_id = Gateway::getClientIdByUid($message_data['other_id']);
                $message = $message_data;
                if ($to_client_id) {
                    foreach ($to_client_id as $key => $value) {
                        Gateway::sendToClient($value, json_encode($message));
                    }
                }
                return;

            case 'get_friend':
                $to_client_id = Gateway::getClientIdByUid($message_data['other_id']);
                if ($to_client_id) {
                    foreach ($to_client_id as $key => $value) {
                        Gateway::sendToClient($value, json_encode($message_data));
                    }
                }
                Gateway::sendToCurrentClient(json_encode($message_data));
                return;
            case 'add_group':
                $to_client_id = Gateway::getClientIdByUid($message_data['user_id']);
                $message = $message_data;
                if ($to_client_id) {
                    foreach ($to_client_id as $key => $value) {
                        Gateway::sendToClient($value, json_encode($message));
                    }
                }
                return;
        }
    }

    /**
     * 当客户端断开连接时
     * @param integer $client_id 客户端id
     */
    public static function onClose($client_id)
    {
        // debug
        echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id onClose:''\n";

        // 从房间的客户端列表中删除
        if (isset($_SESSION['room_id'])) {
            $room_id = $_SESSION['room_id'];
            $new_message = array('type' => 'logout', 'from_client_id' => $client_id, 'from_client_name' => $_SESSION['client_name'], 'time' => date('Y-m-d H:i:s'));
            // if (strpos($_SESSION['client_name'], 'custom') !== false) {
            //     db('chat_rooms')->where('room_id', $_SESSION['room_id'])->setField('status', 1);
            //     //file_put_contents('txt.txt', '--'.$_SESSION['room_id']);
            // }
            // file_put_contents('txt.txt',$_SESSION['client_name'].PHP_EOL,FILE_APPEND);
            Gateway::sendToGroup($room_id, json_encode($new_message));
        }
    }
}
